native-dns -- A replacement DNS stack for node.js
Installation
npm install native-dns
and then var dns = require('native-dns');
Client
native-dns exports what should be a 1:1 mapping of the upstream node.js dns
module. That is to say if it's listed in the docs
it should behave similarly. If it doesn't please file an issue
Request
Beyond matching the upstream module, native-dns also provides a method for
customizing queries.
var dns = require('../dns'),
util = require('util');
var question = dns.Question({
name: 'www.google.com',
type: 'A',
});
var start = Date.now();
var req = dns.Request({
question: question,
server: { address: '8.8.8.8', port: 53, type: 'udp' },
timeout: 1000,
});
req.on('timeout', function () {
console.log('Timeout in making request');
});
req.on('message', function (err, answer) {
answer.answer.forEach(function (a) {
console.log(a.address);
});
});
req.on('end', function () {
var delta = (Date.now()) - start;
console.log('Finished processing request: ' + delta.toString() + 'ms');
});
req.send();
Request creation takes an object with the following fields
question
-- an instance of Question (required)server
-- defines the remote end point (required)
- as an object it should be
address
-- a string ip address (required)port
-- a number for the remote port (optional, default 53)type
-- a string indicating udp
or tcp
(optional, default udp
)
You do not need to indicate ipv4 or ipv6, the backend will handle that
- a string ip address
timeout
-- a number in milliseconds indicating how long to wait for the
request to finish. (optional, default 4000)try_edns
-- a boolean indicating whether to use an EDNSPacket
(optional)cache
-- can be false to disable caching, or implement the cache model, or
an instance of Cache but with a different store (optional, default
platform.cache)
There are only two methods
send
-- sends the actual request to the remote endpointcancel
-- cancels the request and ignores any responses
Request emits the following events
message
-- This is where you get a response, passes (err, answer)
where
answer is an instance of Packet
timeout
-- Fired when the timeout is reachedcancelled
-- Fired if the request is cancelledend
-- Always fired after a request finished, regardless of disposition
Platform
If you want to customize all resolve
or lookup
s with the replacement client
stack you can modify the platform settings accessible in the top level platform
object.
Methods:
reload
-- Re-read system configuration files to populate name servers and
hosts
Properties:
ready
-- Boolean whether requests are safe to transit, true after hosts
and name servers are filledwatching
-- Boolean indicating if system configuration files are watched
for changes, default to false (currently can only be enabled on !win32)name_servers
-- An array of servers used for resolving queries against
- Each entry is an object of
{ address: <string ip>, port: 53 }
- On win32 this is hard coded to be google dns until there's a sane way to get
the data
search_path
-- An array of domains to try and append after a failed lookupattempts
-- The number of retries for a failed lookup/timeout (default: 5)timeout
-- The time each query is allowed to take before trying another
server. (in milliseconds, default: 5000 (5 seconds))edns
-- Whether to try and send edns queries first (default: false)cache
-- The system wide cache used by default for lookup
and resolve
,
set this to false to disable caching
Events:
ready
-- Emitted after hosts and name servers have been loadedunready
-- Emitted when hosts and name servers configuration is being
reloaded.
Server
There is also a rudimentary server implementation
var dns = require('../dns'),
server = dns.createServer();
server.on('request', function (request, response) {
response.answer.push(dns.A({
name: request.question[0].name,
address: '127.0.0.1',
ttl: 600,
}));
response.answer.push(dns.A({
name: request.question[0].name,
address: '127.0.0.2',
ttl: 600,
}));
response.additional.push(dns.A({
name: 'hostA.example.org',
address: '127.0.0.3',
ttl: 600,
}));
response.send();
});
server.on('error', function (err, buff, req, res) {
console.log(err.stack);
});
server.serve(15353);
Server creation
createServer
and createUDPServer
-- both create a UDP
based server,
they accept an optional object for configuration,
{ dgram_type: 'udp4' }
is the default option, the other is udp6
createTCPServer
-- creates a TCP based server
Server methods
serve(port, [address])
-- specify which port and optional address to listen
onclose()
-- stop the server/close sockets.
Server events
listening
-- emitted when underlying socket is listeningclose
-- emitted when the underlying socket is closedrequest
-- emitted when a dns message is received, and the packet was
successfully unpacked, passes (request, response)
- Both
request
and response
are instances of Packet
when you're finished
creating the response, you merely need to call .send()
and the packet will
DoTheRightThing
error
-- emitted when unable to properly unpack the packet, passed (err, msg, response)
socketError
-- remap of the underlying socket for the server, passes (err, socket)
Packet
Properties:
id
-- request idqdcount
-- the number of questions (inferred from array size)ancount
-- the number of questions (inferred from array size)nscount
-- the number of questions (inferred from array size)arcount
-- the number of questions (inferred from array size)qr
-- is a query responseopcode
aa
-- Authoritative Answertc
-- Truncation bitrd
-- Recursion Desiredra
-- Recursion Availableres1
-- Reserved fieldres2
-- Reserved fieldres3
-- Reserved fieldrcode
-- Response Code (see consts.NAME_TO_RCODE
)
question
-- array of Question
sanswer
-- array of ResourceRecord
sauthority
-- array of ResourceRecord
sadditional
-- array of ResourceRecord
s
Methods:
send()
-- Handles sending the packet to the right end point
Question
A Question
is instantiated by passing an object like:
name
-- i.e. 'www.google.com' (required)type
-- Either the string representation of the record type, or the integer
value, see consts.NAME_TO_QTYPE
(default: 'A')class
-- The class of service, default to 1 meaning internet
ResourceRecord
ResourceRecords are what populate answer
, authority
, and additional
.
This is a generic type, and each derived type inherits the following properties:
name
-- The name of the resourcetype
-- The numerical representation of the resource record typeclass
-- The numerical representation of the class of service (usually 1 for internet)ttl
-- The Time To Live for the record, in seconds
Available Types:
primary
-- stringadmin
-- stringserial
-- numberrefresh
-- numberretry
-- numberexpiration
-- numberminimum
-- number
priority
-- numberexchange
-- string
priority
-- numberweight
-- numberport
-- numbertarget
-- string
order
-- numberpreference
-- numberflags
-- stringservice
-- stringregexp
-- stringreplacement
-- string